package seedream

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"time"

	"gitee.com/zhyclouds/fable-scribe/internal/domain"
	"gitee.com/zhyclouds/fable-scribe/internal/service/image"
	"github.com/spf13/viper"
)

// SeedreamImageService Doubao Seedream图像生成服务实现
type SeedreamImageService struct {
	apiKey  string
	baseURL string
	modelID string
	client  *http.Client
}

// NewSeedreamImageService 创建新的Seedream图像生成服务实例
func NewSeedreamImageService() image.Service {
	apikey := viper.GetString("ARK_API_KEY")
	if apikey == "" {
		panic("未读取到 openai-key")
	}

	return &SeedreamImageService{
		apiKey:  apikey,
		baseURL: "https://ark.cn-beijing.volces.com/api/v3/images/generations",
		modelID: "doubao-seedream-4-0-250828",
		client: &http.Client{
			Timeout: time.Second * 60 * 10, // 设置较长的超时时间，图像生成通常需要更多时间
		},
	}
}

// apiRequest 模型API请求结构体
type apiRequest struct {
	Model                            string             `json:"model"`
	Prompt                           string             `json:"prompt"`
	Size                             string             `json:"size"`
	Watermark                        bool               `json:"watermark"`
	ResponseFormat                   string             `json:"response_format"`
	SequentialImageGeneration        string             `json:"sequential_image_generation,omitempty"`
	SequentialImageGenerationOptions *sequentialOptions `json:"sequential_image_generation_options,omitempty"`
}

// sequentialOptions 组图功能配置结构体
type sequentialOptions struct {
	MaxImages int `json:"max_images,omitempty"`
}

// apiResponse 模型API响应结构体
type apiResponse struct {
	Data []struct {
		URL  string `json:"url,omitempty"`
		B64  string `json:"b64_json,omitempty"`
		Size string `json:"size"`
	} `json:"data"`
	Error struct {
		Message string `json:"message"`
	} `json:"error,omitempty"`
}

// GenerateImage 根据文本提示生成图像
func (s *SeedreamImageService) GenerateImage(ctx context.Context, req domain.ImageGenerationRequest) ([]domain.ImageGenerationResponse, error) {
	// 验证API Key
	if s.apiKey == "" {
		return nil, errors.New("API Key未设置，请设置ARK_API_KEY环境变量")
	}

	// 设置默认值
	requestSize := req.Size
	if requestSize == "" {
		requestSize = "2K"
	}

	responseFormat := req.ResponseFormat
	if responseFormat == "" {
		responseFormat = "url"
	}

	prefix := "请根据内容生成一组漫画。要求一个分镜一张单独的图片。scenes 是分镜文案，scenes_detail 是绘制漫画的 prompt。scenes 和 scenes_detail 一一对应。"
	req.Prompt = prefix + req.Prompt

	// 构建请求体
	apiReq := apiRequest{
		Model:                     s.modelID,
		Prompt:                    req.Prompt,
		Size:                      requestSize,
		Watermark:                 req.Watermark,
		ResponseFormat:            responseFormat,
		SequentialImageGeneration: "auto", // 默认启用组图功能
	}

	// 如果设置了最大图片数量，则添加到配置中
	if req.MaxImages > 0 && req.MaxImages <= 15 {
		apiReq.SequentialImageGenerationOptions = &sequentialOptions{
			MaxImages: req.MaxImages,
		}
	} else if req.MaxImages > 15 {
		// 如果超过最大限制，设置为最大值
		apiReq.SequentialImageGenerationOptions = &sequentialOptions{
			MaxImages: 15,
		}
	}

	reqBody, err := json.Marshal(apiReq)
	if err != nil {
		return nil, fmt.Errorf("序列化请求体失败: %v", err)
	}

	// 创建HTTP请求，使用传入的context
	httpReq, err := http.NewRequestWithContext(ctx, "POST", s.baseURL, bytes.NewBuffer(reqBody))
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", "Bearer "+s.apiKey)

	// 发送请求
	resp, err := s.client.Do(httpReq)
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	// 检查响应状态码
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("API返回错误状态码: %d, 响应: %s", resp.StatusCode, string(respBody))
	}

	// 解析响应
	var apiResp apiResponse
	if err := json.Unmarshal(respBody, &apiResp); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	// 检查API错误
	if apiResp.Error.Message != "" {
		return nil, errors.New(apiResp.Error.Message)
	}

	// 转换为领域响应
	results := make([]domain.ImageGenerationResponse, len(apiResp.Data))
	for i, item := range apiResp.Data {
		results[i] = domain.ImageGenerationResponse{
			Size: item.Size,
		}
		if responseFormat == "url" {
			results[i].URL = item.URL
		} else if responseFormat == "b64_json" {
			results[i].URL = item.B64 // 这里用URL字段存储base64数据
		}
	}

	return results, nil
}
